#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT constructor {name gene args} {
	set this(value) ""
	set this(name) $name 
	set this(gene) $gene	
	#enregistrement aupres de son gene
	if {$gene != ""} {
		$gene add_attribut $objName
	}
}

#___________________________________________________________________________________________________________________________________________
Generate_accessors MAGELLAN__ATTRIBUT [list name]


#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT dispose {} {
	# puts "############dispose $objName#############################################################"
	if {$this(gene) != ""} {
		$this(gene) rem_attribut $objName
	}
	this inherited
	
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT mutation {} {puts stderr "IMPLEMENTER LA MUTATION POUR $objName"}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT value {} {puts stderr "IMPLEMENTER LA METHODE VALUE POUR $objName"}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT is_serializable {} {
	return 1 
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT get_serialization {} {
	return [array get this]
}

#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT cleanCache {} {}

#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ATTRIBUT = {a} {
# puts "#### ATTRIBUT:[lindex [gmlObject info classes $a] 0]: $objName == $a "
if {$a == $objName} {return}
	foreach {var val} [$a get_serialization] {
	#pas de copie du gene, pour ne pas casse les branchements
	if {$var != "gene"} {	set this($var) $val}
	}
}
#___________________________________________________________________________
#___________________________________________________________________________
#___________________________________________________________________________
inherit MAGELLAN__BG MAGELLAN__ATTRIBUT
method MAGELLAN__BG constructor {name gene args} {
	this inherited $name $gene
	set this(valueFG) "inherit"
	set this(valueBG) "inherit"
	if {[lindex $args 0] != {}} {
		set this(valueBG) [lindex $args 0]
		set this(valueFG) [lindex $args 1]
	}
}

#___________________________________________________________________________________________________________________________________________
method MAGELLAN__BG mutation {} {
		set index1  [expr int(rand() *5)]
		set index2  [expr int(rand() *5)]
		set modifications [list identity lighter darker]
		set mod1 [lrand $modifications]
		set mod2 [lrand $modifications]
		set angle [expr int (rand () * 8) * 360 / 8]
		
		set modFG [lrand $modifications]
		set indexFG  [expr int(rand() *5)]
		
		#petite roulette russe
		set this(valueBG) [MAGELLAN__stochastic_switch [list \
		[list 50 [list uniform $mod1 $index1]] \
		[list 10 [list gradient $mod1 $index1 $mod2 $index2 $angle] ] \
		[list 0 "inherit"]]]
		
		set L_color [$this(gene) get_attribute_value MAGELLAN__L_color]
		set currentBG_Color [MAGELLAN__COLOR_MUTATOR $mod1 [lindex $L_color $index1]]
		if {[catch {set this(valueFG) [MAGELLAN__getBetterContrast $currentBG_Color [$this(gene) get_attribute_value MAGELLAN__L_color]]} err]} {
		  error "ERROR in $objName MAGELLAN__BG::mutation\n$err"
		 }
		 set this(value) "" 
}

#___________________________________________________________________________________________________________________________________________
method MAGELLAN__BG value {} {
if {$this(value) == ""} {
	set L_color [$this(gene) get_attribute_value MAGELLAN__L_color]	
	if {[lindex $this(valueBG) 0] == "inherit"  } {
		set old_Value [$this(gene) get_ancestors_attribute_value MAGELLAN__BG]
		if {$old_Value  == ""} {
			set this(valueBG) [list uniform identity 0]			
			set currentBG_Color [MAGELLAN__COLOR_MUTATOR identity [lindex $L_color 0]]
			if {[catch {set this(valueFG) [MAGELLAN__getBetterContrast $currentBG_Color [$this(gene) get_attribute_value MAGELLAN__L_color]]} err]} {  error "ERROR in $objName MAGELLAN__BG::value\n$err"}

		} else {
			set value [lindex $old_Value 2]
			set BG_param [lindex $value 0]
			set FG_param [lindex $value 1]
			set this(value)  [list FCT bg_fg [list $BG_param $FG_param $this(name)]]
			#return [list FCT bg_fg [list $bg $fg $this(name)]]
		}
	}	
	if {[lindex $this(valueBG) 0] == "uniform"} {			
		#get BG1
		set mod_BG1   [lindex $this(valueBG) 1]
		set base_BG1  [lindex $L_color [lindex $this(valueBG) 2]]
		set BG_param [list "uniform" [MAGELLAN__COLOR_MUTATOR $mod_BG1 $base_BG1]]

		#getFG
		set mod_FG   [lindex $this(valueFG) 0]
		set base_FG  [lindex $L_color [lindex $this(valueFG) 1]]
		set FG_param [MAGELLAN__COLOR_MUTATOR $mod_FG $base_FG]

	} 	
	if {[lindex $this(valueBG) 0] == "gradient"} {
		set mod_BG1   [lindex $this(valueBG) 1]
		set base_BG1  [lindex $L_color [lindex $this(valueBG) 2]]
		set mod_BG2   [lindex $this(valueBG) 3]
		set base_BG2  [lindex $L_color [lindex $this(valueBG) 4]]
		set angle [lindex $this(valueBG) 5]
		set BG_param [list "gradient" [MAGELLAN__COLOR_MUTATOR $mod_BG1 $base_BG1] [MAGELLAN__COLOR_MUTATOR $mod_BG2 $base_BG2] $angle]
			
		set mod_FG   [lindex $this(valueFG) 0]
		set base_FG  [lindex $L_color [lindex $this(valueFG) 1]]

		set FG_param [MAGELLAN__COLOR_MUTATOR $mod_FG $base_FG]
	
	} 	
	
	
	if {[MAGELLAN__testContrast [lindex $BG_param 1] $FG_param] < 0.5 } { puts "error contrast is bad = [MAGELLAN__testContrast [lindex $BG_param 1] $FG_param]" }
	set this(value) [list FCT bg_fg [list $BG_param $FG_param $this(name)]]
}
return $this(value) 
}
method MAGELLAN__BG cleanCache {} {	set this(value) "" }
#___________________________________________________________________________________________________________________________________________
proc MAGELLAN__testContrast {L_bg fg} {
	if {[llength [lindex $L_bg 0]] != 1} {
		set bg [lindex $L_bg 0]
	} else {
		set bg $L_bg
	}
	if {$fg == ""} { error "error in MAGELLAN__BG testContrast fg is void, default to black" ; set fg {0 0 0 1}}
	if {$bg == ""} { error "error in MAGELLAN__BG testContrast bg is void, default to white" ; set bg {1 1 1 1}}
	lassign $bg R_bg G_bg B_bg
	lassign $fg R_fg G_fg B_fg
	
	set Y_bg [expr  0.299*$R_bg + 0.587*$G_bg + 0.114*$B_bg]
	set Y_fg [expr  0.299*$R_fg + 0.587*$G_fg + 0.114*$B_fg]
	return [expr max (0, abs($Y_bg - $Y_fg) )]
}

#___________________________________________________________________________________________________________________________________________

proc MAGELLAN__testContrastModificateur {L_bg L_color L_mod} {
	set result [list]
	foreach modificateur $L_mod {
		set i 0
		foreach fg $L_color {
			set cur [MAGELLAN__testContrast $L_bg [MAGELLAN__COLOR_MUTATOR $modificateur $fg]]
			lappend result [list [MAGELLAN_Normal_Seuil_Function $cur] [list $modificateur $i]]
			incr i
		}
	}
	return $result
}
proc MAGELLAN__getBetterContrast {L_bg L_color} {
	if {[llength $L_color] == 0} {error "Error in MAGELLAN__getBetterContrast : L_color vide et L_bg = {$L_bg}"}
	set max -1
	set res [list]
	set mod "identity"
	set result 0
	
	set result [MAGELLAN__stochastic_switch [MAGELLAN__testContrastModificateur $L_bg $L_color [list identity darker lighter contrast white black]]]
	return $result 
}

#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
inherit MAGELLAN__L_color MAGELLAN__ATTRIBUT
method MAGELLAN__L_color constructor {name gene args} {
	this inherited $name $gene
	set this(up_to_date) 0
	set this(cached_values) ""
	set class(nb_color) 5
	set this(L_transformations) [list identity identity identity identity identity]
	set this(original_color) [lindex $args 0]
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color setNbColor {nb} {
	set class(nb_color) $nb
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color mutation {} {
	set L_tranformation [list {10 identity} {1 darker} {1 lighter}]
	set this(L_transformations) [list]
	for {set i 0 } {$i < $class(nb_color) } {incr i} {
		lappend this(L_transformations) [MAGELLAN__stochastic_switch $L_tranformation]
	}
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color changeLuminance {C d} {
    if {[llength $C] != 4} {
	  error "BLAIREAU !!!\n  $objName MAGELLAN__L_color::changeLuminance {$C} {$d}"
	 }
	lassign $C R G B A
	set Y [expr  0.299*$R + 0.587*$G + 0.114*$B]
	set U [expr ($B-$Y)*0.565]
	set V [expr ($R-$Y)*0.713]

	set Y [expr max ($Y,0.01)  * $d]
	set R [expr $Y + 1.403*$V]
	set G [expr $Y - 0.344*$U - 0.714*$V]
	set B [expr $Y + 1.770*$U]
	foreach e "R G B" {
		set $e [string range [expr min(1 ,max(0, [set $e]))] 0 6]
	}
	return [list $R $G $B $A]
}
method MAGELLAN__L_color cleanCache {} {
	set this(value) "" 
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color lighter {C} {return [this changeLuminance $C 1.5] }
method MAGELLAN__L_color darker {C} {return [this changeLuminance $C 0.7] }
method MAGELLAN__L_color white {C} {return [list 1 1 1 1] }
method MAGELLAN__L_color black {C} {return [list 0 0 0 1] }
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color contrast {C} {
	lassign $C R G B A
	if {[llength $C] != 4} {
	  error "BLAIREAU !!!\n  $objName MAGELLAN__L_color::contrast {$C}"
	 }
	set Y [expr  0.299*$R + 0.587*$G + 0.114*$B]
	
	set U [expr ($B-$Y)*0.565]
	set V [expr ($R-$Y)*0.713]
	if {$Y < 0.5} {
		set Y [expr min ($Y + 1.7,1)]
	} else {
		set Y [expr max ($Y - 1.7,0)]
	}

	set R [expr $Y + 1.403*$V]
	set G [expr $Y - 0.344*$U - 0.714*$V]
	set B [expr $Y + 1.770*$U]
	foreach e "R G B" {
		set $e [string range [expr min(1 ,max(0, [set $e]))] 0 16]
	}

	return [list $R $G $B $A]

}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color identity {C} {return $C }
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color value {} {
	set ancestors_values [$this(gene) get_ancestors_attribute_value MAGELLAN__L_color]
	if {$ancestors_values == ""} {set ancestors_values [[$this(gene) get_individu] get_L_color]}
	set this(cached_values)  [list]
	foreach value $ancestors_values  transformation $this(L_transformations) {
		lappend this(cached_values) [this $transformation $value]
	}
	return $this(cached_values)
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__L_color is_serializable {} {
	return 0
}




#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
inherit MAGELLAN__INITIAL_L_COLOR MAGELLAN__L_color
method MAGELLAN__INITIAL_L_COLOR constructor {name gene listColor} {
	this inherited $name $gene
	set this(up_to_date) 1
	set this(cached_values) $listColor
}





#________________________________________________________________________________________________________________________________________
#________________________________________________________________________________________________________________________________________
#________________________________________________________________________________________________________________________________________
inherit MAGELLAN__GDD_IMPLEMENTATION MAGELLAN__ATTRIBUT
method MAGELLAN__GDD_IMPLEMENTATION constructor {name gene args} {
	this inherited $name $gene
	set class(dsl_gdd) [[[$this(gene) get_individu] get_root]  get_DSL_GDD_QUERY]
	set this(cached_value) [lindex $args 0]
	
	set typeTargets [$this(gene) get_typeTargets]
	if {[llength $typeTargets] == 1} {
		set this(type) [lindex $typeTargets 1]
	}
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__GDD_IMPLEMENTATION mutation { {fichier {}}} {
	global err_fichier

	set typeTargets [$this(gene) get_typeTargets]
	
	
	if {[llength $typeTargets] == 1} {
		set this(type) [lindex [lindex $typeTargets 0] 1]
		
		
		$class(dsl_gdd) QUERY  "?n : $this(type) : NODE()<-REL(type ~= GDD_inheritance)*<-\$n(type == GDD_CUI)<-REL(type == GDD_implementation)<-NODE(ptf == Ptf_HTML)"
		set L_CUI [lindex [lindex [$class(dsl_gdd) get_Result] 0] 1]
		set rep [lindex $L_CUI [expr int(rand()*[llength $L_CUI])]]
		set this(cached_value) $rep
		
		
		#mise a jour des attributs du genes 
		$class(dsl_gdd) QUERY "?n : $rep : NODE()->REL(type ~= GDD_inheritance)*->\$n()"
		set GDD_nodes [lindex [lindex [$class(dsl_gdd) get_Result] 0] 1]
		lappend GDD_nodes $rep
		$class(dsl_gdd) QUERY  "?n : $rep : NODE()<-REL(type ~= GDD_inheritance)*<-\$n(ptf == Ptf_HTML)"
		set GDD_nodes [concat $GDD_nodes [lindex [lindex [$class(dsl_gdd) get_Result] 0] 1]]
		
		
		
		set L_attributes [list]
		foreach node $GDD_nodes {
			
			set L_attributes [concat $L_attributes [$node get_L_attributs]]
		}
		
			
		#on enleve les anciens attributs specific au CUI
		foreach att [$this(gene) get_L_attributes] {
			if {[string match "*_CUI_specific" $att]} {
				if [info exist $att] {		if [catch {$att dispose}{err }] {puts stderr $err }}
			}
		}
		

		foreach att $L_attributes {
			if {$att != {}} {		
				set attribut [lindex $att 0]
				set name [lindex $att 1]
				
				set alreadyIn 0
				foreach gene_attribut [$this(gene) get_L_attributes] {
					
					set gene_attribut_class [lindex [gmlObject info classes $gene_attribut] 0]
					set gene_attribut_name  [$gene_attribut get_name]
					
					if { [string equal $attribut $gene_attribut_class] && ([lindex $att 1] == {} || $gene_attribut_name == $name)} {
						set alreadyIn 1
					} 
				}	
				if {!$alreadyIn} {
					set objectName [CPool get_a_unique_name]_CUI_specific													
					if [catch {set result [[lindex $att 0] $objectName [lindex $att 1] $this(gene) [lindex $att 2]]} {err}] {puts stderr $err}
				}
			}
		}
	}
} 

#___________________________________________________________________________________________________________________________________________
method  MAGELLAN__GDD_IMPLEMENTATION value {} {
	if {$this(cached_value) == ""} {
		return "" 
	}
	set typeTargets [$this(gene) get_typeTargets]
	if {[llength $typeTargets] == 1} {
		if {$this(type) == [lindex [lindex $typeTargets 0] 1]	} {
			return [list GDD Implem $this(cached_value)]
		} else {
			set this(cached_value) ""
		}
	}

}
 

#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
inherit MAGELLAN__Column MAGELLAN__ATTRIBUT 
method MAGELLAN__Column constructor {name gene args} {
	puts "column"
    this inherited $name $gene
    set this(value) 0
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__Column mutation {} {
    set this(value) [expr 0 + int (rand () * 5) ]
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__Column value {} {
    return [list FCT Column $this(value)]
}

#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
inherit MAGELLAN__Border MAGELLAN__ATTRIBUT 
method MAGELLAN__Border constructor {name gene args} {
    this inherited $name $gene
	set L_color [$this(gene) get_attribute_value MAGELLAN__L_color]
	set currentBG_Color [MAGELLAN__COLOR_MUTATOR identity [lindex $L_color 0]]
	if {[catch {set this(Color) [MAGELLAN__getBetterContrast $currentBG_Color $L_color]} err]} {
	  error "ERROR in $objName MAGELLAN__Border::constructor\n     gene : $this(gene)\n  L_color : {$L_color}"
	 }
	set this(Radius) 1
	set this(size) 1 
	set this(type) solid
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__Border mutation {} {
		set this(size)  [expr int(rand() *5)]
		set this(Radius) [expr int (rand () * 10) ]
		set index1  [expr int(rand() *5)]
		set modifications [list identity lighter darker]
		set mod1 [lrand $modifications]
		set this(Color) [list $mod1 $index1]
		set this(type) [lrand [list solid]]
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__Border value {} {

	set L_color [$this(gene) get_attribute_value MAGELLAN__L_color]
	#get BG1
	set mod1   [lindex $this(Color) 0]
	set base1  [lindex $L_color [lindex $this(Color) 1]]
	return [list FCT Border [list $this(size) $this(type)  [MAGELLAN__COLOR_MUTATOR $mod1 $base1] $this(Radius) $this(name)] ]
}



#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
inherit MAGELLAN__ENCAPSULATION MAGELLAN__ATTRIBUT 
method MAGELLAN__ENCAPSULATION constructor {name gene args} {
    this inherited $name $gene
	set this(possibleValue) [lindex $args 0]
  set this(value) {}
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ENCAPSULATION mutation {} {
    set this(value) [lrand $this(possibleValue)]
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__ENCAPSULATION value {} {
		if {$this(value) != {} } {
			return [list FCT enrich $this(value)]
		}
}

#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
inherit MAGELLAN__REORDER MAGELLAN__ATTRIBUT 
method MAGELLAN__REORDER constructor {name gene args} {
    this inherited $name $gene
    set this(value) 0
}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__REORDER mutation {} {
    set this(value) [expr int(rand() * 4294967295)]
}

#___________________________________________________________________________________________________________________________________________
method MAGELLAN__REORDER value {} {
    return [list FCT Reorder $this(value)]
}

#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
#___________________________________________________________________________________________________________________________________________
inherit MAGELLAN__FLOAT MAGELLAN__ATTRIBUT 
method MAGELLAN__FLOAT constructor {name gene args} {
    this inherited $name $gene

}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__FLOAT mutation {} {
    set this(value) [lrand [list "" "left" "right" "center"]]
}

#___________________________________________________________________________________________________________________________________________
method MAGELLAN__FLOAT value {} {
    if {$this(value) != ""} {
		return [list FCT Float_daughters $this(value)]
	}
	return ""
}


inherit MAGELLAN__FLOAT_DAUGHTERS MAGELLAN__ATTRIBUT 
method MAGELLAN__FLOAT_DAUGHTERS constructor {name gene args} {
    this inherited $name $gene

}
#___________________________________________________________________________________________________________________________________________
method MAGELLAN__FLOAT_DAUGHTERS mutation {} {
    set this(value) [lrand [list "" "left" "right"]]
}

#___________________________________________________________________________________________________________________________________________
method MAGELLAN__FLOAT_DAUGHTERS value {} {
    if {$this(value) != ""} {
		return [list FCT Float $this(value)]
	}
	return ""
}

#___________________________________________________________________________________________________________________________________________
if {![gmlObject info exists object MAGELLAN__COLOR_MUTATOR]} {
MAGELLAN__L_color MAGELLAN__COLOR_MUTATOR "" "" 
}
